using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using needle.UI.Controls.Flat.Windows.Forms;
using needle.UI.Controls.Flat.Utilities.Drawing;
using needle.UI.Controls.Flat.Windows.Forms.Helpers;
using needle.UI.Controls.Flat.Windows.Forms.Collections;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	public class Target
	{
		#region Nested types

		public enum TargetActions
	    {
	        Transfer,
	        GroupLeft,
	        GroupRight,
	        GroupTop,
	        GroupBottom
	    }

		#endregion
	    
	    protected Rectangle mhotRect;
        protected Rectangle mdrawRect;
        protected TabGroupLeaf mleaf;
        protected TargetActions maction;

		#region Constructors
		
		public Target(Rectangle hotRect, Rectangle drawRect, TabGroupLeaf leaf, TargetActions action)
        {
            mhotRect = hotRect;
            mdrawRect = drawRect;
            mleaf = leaf;
            maction = action;
        }

		#endregion

		#region Properties

		public Rectangle HotRect
        {
            get { return mhotRect; }
        }	    
        
        public Rectangle DrawRect
        {
            get { return mdrawRect; }
        }	    

        public TabGroupLeaf Leaf
        {
            get { return mleaf; }
        }

        public TargetActions Action
        {
            get { return maction; }
        }

		#endregion
	}
	
	public class TargetManager
	{
	    protected const int mrectWidth = 4;
        protected static Cursor mvalidCursor;
        protected static Cursor minvalidCursor;
	
        protected TabbedGroups mhost;
        protected TabGroupLeaf mleaf;
	    protected needle.UI.Controls.Flat.Windows.Forms.TabControl msource;
        protected Target mlastTarget;
        protected TargetCollection mtargets;
	    
		#region Constructors

		static TargetManager()
	    {
            mvalidCursor = DrawHelpers.LoadCursor(Type.GetType("needle.UI.Controls.Flat.Windows.Forms.TabbedGroups"),
                                                                  "needle.UI.Controls.Flat.Windows.Forms.Resources.TabbedValid.cur");

            minvalidCursor = DrawHelpers.LoadCursor(Type.GetType("needle.UI.Controls.Flat.Windows.Forms.TabbedGroups"),
                                                                    "needle.UI.Controls.Flat.Windows.Forms.Resources.TabbedInvalid.cur");
        }
	    
	    public TargetManager(TabbedGroups host, TabGroupLeaf leaf, needle.UI.Controls.Flat.Windows.Forms.TabControl source)
	    {
	        mhost = host;
	        mleaf = leaf;
	        msource = source;
	        mlastTarget = null;
	    
	        mtargets = new TargetCollection();
	        
	        TabGroupLeaf tgl = host.FirstLeaf();
	        
	        while(tgl != null)
	        {
	            CreateTargets(tgl);
	        
	            tgl = host.NextLeaf(tgl);
	        }
	    }

		#endregion

		#region Protecteds
	    
	    protected void CreateTargets(TabGroupLeaf leaf)
	    {
	        needle.UI.Controls.Flat.Windows.Forms.TabControl tc = leaf.GrouparamControl as needle.UI.Controls.Flat.Windows.Forms.TabControl;

            Rectangle totalSize = tc.RectangleToScreen(tc.ClientRectangle);

            if (leaf != mleaf)
            {
                Rectangle tabsSize = tc.RectangleToScreen(tc.TabsAreaRect);

                mtargets.Add(new Target(tabsSize, totalSize, leaf, Target.TargetActions.Transfer));
            }
	        
	        if ((leaf != mleaf) || ((leaf == mleaf) && mleaf.TabPages.Count > 1))
	        {
	            int horzThird = totalSize.Width / 3;
	            int vertThird = totalSize.Height / 3;
	        
                Rectangle leftRect = new Rectangle(totalSize.X, totalSize.Y, horzThird, totalSize.Height);
                Rectangle rightRect = new Rectangle(totalSize.Right - horzThird, totalSize.Y, horzThird, totalSize.Height);
                Rectangle topRect = new Rectangle(totalSize.X, totalSize.Y, totalSize.Width, vertThird);
                Rectangle bottomRect = new Rectangle(totalSize.X, totalSize.Bottom - vertThird, totalSize.Width, vertThird);

                TabGroupSequence tgs = mleaf.Parent as TabGroupSequence;

                if (tgs.Count <= 1)
                {
                    mtargets.Add(new Target(leftRect, leftRect, leaf, Target.TargetActions.GroupLeft));
                    mtargets.Add(new Target(rightRect, rightRect, leaf, Target.TargetActions.GroupRight));
                    mtargets.Add(new Target(topRect, topRect, leaf, Target.TargetActions.GroupTop));
                    mtargets.Add(new Target(bottomRect, bottomRect, leaf, Target.TargetActions.GroupBottom));
                }
                else
                {
                    if (tgs.Direction == Direction.Vertical)
                    {
                        mtargets.Add(new Target(topRect, topRect, leaf, Target.TargetActions.GroupTop));
                        mtargets.Add(new Target(bottomRect, bottomRect, leaf, Target.TargetActions.GroupBottom));
                    }
                    else
                    {
                        mtargets.Add(new Target(leftRect, leftRect, leaf, Target.TargetActions.GroupLeft));
                        mtargets.Add(new Target(rightRect, rightRect, leaf, Target.TargetActions.GroupRight));
                    }
                }
            }
	        
            if (leaf != mleaf)
            {
                mtargets.Add(new Target(totalSize, totalSize, leaf, Target.TargetActions.Transfer));
            }
        }

		#endregion
	    
		#region Methods
		
		public void MouseMove(Point mousePos)
	    {
	        Target t = mtargets.Contains(mousePos);
	    
	        if (t != null)
                msource.Cursor = mvalidCursor;
            else
                msource.Cursor = minvalidCursor;
                
            if (t != mlastTarget)
            {
                if (mlastTarget != null)
                    GraphicsUtils.DrawDragRectangle(mlastTarget.DrawRect, mrectWidth);
                
                if (t != null)
                    GraphicsUtils.DrawDragRectangle(t.DrawRect, mrectWidth);
                
                mlastTarget = t;
            }
        }
        
        public void Exit()
        {
            Quit();

            if (mlastTarget != null)
            {
                switch(mlastTarget.Action)
                {
                    case Target.TargetActions.Transfer:
                        mleaf.MovePageToLeaf(mlastTarget.Leaf);
                        break;
                    case Target.TargetActions.GroupLeft:                        
                        mlastTarget.Leaf.NewHorizontalGroup(mleaf, true);
                        break;
                    case Target.TargetActions.GroupRight:
                        mlastTarget.Leaf.NewHorizontalGroup(mleaf, false);
                        break;
                    case Target.TargetActions.GroupTop:
                        mlastTarget.Leaf.NewVerticalGroup(mleaf, true);
                        break;
                    case Target.TargetActions.GroupBottom:
                        mlastTarget.Leaf.NewVerticalGroup(mleaf, false);
                        break;
                }
            }
        }
            
        public void Quit()
        {
            if (mlastTarget != null)
                GraphicsUtils.DrawDragRectangle(mlastTarget.DrawRect, mrectWidth);
        }
        
        public static void DrawDragRectangle(Rectangle rect)
        {
            GraphicsUtils.DrawDragRectangle(rect, mrectWidth);
        }

		#endregion
	}
}
